package com.zj.osm.view.map.offline

import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.ProgressBar
import android.widget.SeekBar
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.KeyboardUtils
import com.zj.osm.R
import com.zj.osm.view.map.offline.test.OSMMapTilePackager
import com.zj.utils.utils.utilcode.NetworkUtils
import com.zj.utils.utils.utilcode.ToastUtils
import kotlinx.android.synthetic.main.activity_down_offline_map_config.*
import org.osmdroid.tileprovider.cachemanager.CacheManager
import org.osmdroid.util.BoundingBox
import org.osmdroid.util.IterableWithSize
import org.osmdroid.util.MapTileArea
import org.osmdroid.util.MapTileAreaList
import java.io.File
import java.text.DecimalFormat
import kotlin.concurrent.thread

class DownOfflineMapConfigActivity : AppCompatActivity(), SeekBar.OnSeekBarChangeListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_down_offline_map_config)
        initData()
        initView()
    }

    private fun initView() {
        downConfigTitleBar.setTitle("离线地图下载")
        downConfigTitleBar.setBackImageVisiable(true)
        downConfigTitleBar.setRightText("确定")
        downConfigSeekBar.progress = 16
        downConfigSeekBar.setOnSeekBarChangeListener(this)
        downConfigSeek.text = "${downConfigSeekBar.progress}级"
        val num = getTileNum(downConfigSeekBar.progress)
        //downConfigTier.text = "（${num}瓦片,预计${formatFileSizes(num)}）"
        downConfigTier.text = "（${num}瓦片,预计${getDownSize(downConfigSeekBar.progress)}）"
        downConfigTitleBar.setRightTextOnClickListener {
            downMap()
        }

    }

    private var north: Double = 0.0
    private var south: Double = 0.0
    private var east: Double = 0.0
    private var west: Double = 0.0

    private fun initData() {
        north = intent.getDoubleExtra("north", 0.0)
        south = intent.getDoubleExtra("south", 0.0)
        east = intent.getDoubleExtra("east", 0.0)
        west = intent.getDoubleExtra("west", 0.0)
    }

    private fun downMap() {
        val name = downConfigName.text.toString()
        if (name.isEmpty() || name == "") {
            ToastUtils.showShort("请输入名称")
            return
        }
        KeyboardUtils.hideSoftInput(this)
        if (downConfigSeekBar.progress < 1) {
            ToastUtils.showShort("下载地图级别太小，请调整下载级别")
            return
        }
        if (File(Environment.getExternalStorageDirectory().path + "/osmdroid/" + name + ".gemf").exists()) {
            ToastUtils.showShort("本地已存在同名文件，请修改名称")
            return
        }
        if (!NetworkUtils.isConnected()) {
            ToastUtils.showShort("网络未连接，请检查网络状况")
            return
        }
        down(name, downConfigSeekBar.progress)
    }

    private fun down(downName: String, maxZoom: Int) {
        val viewDialog = View.inflate(this, R.layout.layout_dialog_down, null)
        viewDialog.measure(viewDialog.measuredWidth, viewDialog.measuredHeight)
        val downDgDownNumber = viewDialog.findViewById<TextView>(R.id.downDgDownNumber)
        val downDgProgressbar = viewDialog.findViewById<ProgressBar>(R.id.downDgProgressbar)
        val downDgTit = viewDialog.findViewById<TextView>(R.id.downDgTit)
        //显示确认框
        val mAlertDialog = AlertDialog.Builder(this).setView(viewDialog).create()
        //设置点击屏幕不消失
        mAlertDialog.setCanceledOnTouchOutside(false)
        //设置点击返回键不消失
        mAlertDialog.setCancelable(false)
        mAlertDialog.show()
        val num = getTileNum(downConfigSeekBar.progress)
        downDgDownNumber.text = "0/${num}"
        downDgProgressbar.max = num
        var size = 0
        val destinationFile: String? = Environment.getExternalStorageDirectory().path + "/osmdroid/"
        val tempFolder: String = Environment.getExternalStorageDirectory().path + "/Mapnik"
        val threadCount = Runtime.getRuntime().availableProcessors() * 2 + 1
        isFolderExists(tempFolder)

        thread {
            OSMMapTilePackager.execute(
                    "https://mt0.google.cn/vt/lyrs=y&scale=2&hl=zh-CN&gl=CN&src=app&x=%d&y=%d&z=%d",
                    "$destinationFile$downName.gemf",
                    tempFolder, threadCount, "",
                    0, maxZoom, north, south, east, west
            ) {
                //Log.e("哈哈哈", "和哈说 $it")
                runOnUiThread {
                    if (it.contains("Downloading")) {
                        size++
                        downDgProgressbar.progress = size
                        downDgDownNumber.text = "${size}/${num}"
                    } else {
                        if (it.contains("Download")) {
                            downDgProgressbar.progress = num
                            downDgDownNumber.text = "${num}/${num}"
                            downDgTit.text = "下载已完成，正在打包，请耐心等待..."
                        } else if (it.contains("Arching")) {
                            ToastUtils.showShort("下载完成")
                            mAlertDialog.dismiss()
                            finish()
                        }
                    }
                }
            }
        }

    }


    private fun isFolderExists(strFolder: String) {
        val file = File(strFolder)
        if (!file.exists()) {
            file.mkdir()
        }
    }

    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        val num = getTileNum(progress)
        //downConfigTier.text = "（${num}瓦片,预计${formatFileSizes(num)}）"
        downConfigTier.text = "（${num}瓦片,预计${getDownSize(progress)}）"
        downConfigSeek.text = "${progress}级"
    }

    private fun getTileNum(progress: Int): Int {
        val bb = BoundingBox(north, east, south, west) //北东南西
        return getTilesCoverageIterable(bb, 0, progress)!!.size()
    }

    private fun getTilesCoverageIterable(pBB: BoundingBox?,
                                         pZoomMin: Int, pZoomMax: Int): IterableWithSize<Long?>? {
        val list = MapTileAreaList()
        for (zoomLevel in pZoomMin..pZoomMax) {
            list.list.add(MapTileArea().set(zoomLevel, CacheManager.getTilesRect(pBB, zoomLevel)))
        }
        return list
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {}

    override fun onStopTrackingTouch(seekBar: SeekBar?) {}


    private fun getDownSize(zoom: Int): String {
        var num = 0
        for (index in 0..zoom) {
            when (index) {
                0 -> {
                    num += 35
                }
                1, 2, 3, 4, 5 -> {
                    val size = (getTileNum(index) - getTileNum(index - 1)) * 55
                    num += size
                }
                6, 7, 8, 9, 10, 11, 12, 13, 14, 15 -> {
                    val size = (getTileNum(index) - getTileNum(index - 1)) * 100
                    num += size
                }
                16, 17 -> {
                    val size = (getTileNum(index) - getTileNum(index - 1)) * 70
                    num += size
                }
                18 -> {
                    val size = (getTileNum(index) - getTileNum(index - 1)) * 40
                    num += size
                }
                19 -> {
                    val size = (getTileNum(index) - getTileNum(index - 1)) * 30
                    num += size
                }
            }
        }
        return formatFileSize(num)
    }

}
